# iOS_CheckToolPage.py (最终重构版)
import os
import threading
import time
import tkinter as tk
import platform
from tkinter import ttk, filedialog, messagebox

# --- 导入重构后的纯逻辑函数 ---
# 确保 iOS_check.py 和 iOS_packing.py 都已经是纯逻辑模块
from checktools.iOS_check import get_full_check_results, get_connected_ios_devices
from packingtools.iOS_packing import upload_project_to_wsl

# --- 统一浅色主题变量 ---
BG_LIGHT = "#ffffff"
ACCENT = "#2563eb"
TEXT_DARK = "#1e293b"
TEXT_MUTED = "#64748b"
OK_GREEN = "#137333"
ERROR_RED = "#d93025"
WARN_ORANGE = "#ea4335"


class iOS_CheckToolPage(tk.Frame):
    """浅色主题 iOS/WSL 环境检测 & 打包工具 (UI层)"""

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # --- 状态变量 ---
        self._alive = True
        self._detection_in_progress = False
        self.project_root = tk.StringVar()

        # --- 字体 ---
        self.title_font = ("Segoe UI", 14, "bold")
        self.subtitle_font = ("Segoe UI", 10)

        self._setup_widgets()
        self.after(500, self.start_check)  # 启动后自动检测一次

    def destroy(self):
        """安全销毁窗口和后台任务标志"""
        self._alive = False
        # 销毁可能存在的子窗口
        if hasattr(self, "_pack_win") and self._pack_win.winfo_exists():
            self._pack_win.destroy()
        super().destroy()

    # ------------------------------------------------------------------
    # 界面构建 (Setup Widgets)
    # ------------------------------------------------------------------
    def _setup_widgets(self):
        main = ttk.Frame(self)
        main.pack(fill=tk.BOTH, expand=True)

        # 头部
        header = ttk.Frame(main)
        header.pack(fill=tk.X, pady=(0, 10))
        ttk.Label(header, text="iOS 开发环境检测 & 打包工具", font=self.title_font, foreground=ACCENT).pack(
            side=tk.LEFT)
        self.time_lbl = ttk.Label(header, text="", font=self.subtitle_font, foreground=TEXT_MUTED)
        self.time_lbl.pack(side=tk.RIGHT)

        # 项目配置区
        path_frm = ttk.LabelFrame(main, text="项目配置", padding=10)
        path_frm.pack(fill=tk.X, pady=(0, 10))
        path_frm.columnconfigure(1, weight=1)
        ttk.Label(path_frm, text="项目根目录：").grid(row=0, column=0, sticky=tk.W, padx=(0, 5), pady=5)
        ttk.Entry(path_frm, textvariable=self.project_root).grid(row=0, column=1, sticky=tk.EW, pady=5)
        ttk.Button(path_frm, text="浏览…", command=self.browse_folder).grid(row=0, column=2, padx=5, pady=5)
        ttk.Button(path_frm, text="编译打包", style="Accent.TButton", command=self.build_project).grid(row=0, column=3,
                                                                                                       padx=(5, 0),
                                                                                                       pady=5)

        # 功能选项卡
        nb = ttk.Notebook(main)
        nb.pack(fill=tk.BOTH, expand=True)

        self.env_tree = self._create_tree_tab(nb, "环境依赖")
        self.devices_tree = self._create_tree_tab(nb, "连接设备")

        # 底部按钮
        btn_frm = ttk.Frame(main)
        btn_frm.pack(fill=tk.X, pady=(10, 0))
        ttk.Button(btn_frm, text="一键检测", style="Accent.TButton", command=self.start_check).pack(side=tk.LEFT)

        self._configure_styles()

    def _create_tree_tab(self, notebook, text):
        """辅助函数，用于创建带滚动条的Treeview选项卡"""
        tab = ttk.Frame(notebook)
        notebook.add(tab, text=text)

        tree = ttk.Treeview(tab, show="tree", selectmode="none")
        tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(5, 0), pady=5)

        scrollbar = ttk.Scrollbar(tab, orient="vertical", command=tree.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y, padx=(0, 5), pady=5)
        tree.configure(yscrollcommand=scrollbar.set)

        return tree

    def _configure_styles(self):
        """集中配置所有控件样式"""
        style = ttk.Style()
        style.configure("Accent.TButton", font=("Segoe UI", 10, "bold"))

        tag_colors = {
            "error": ERROR_RED, "ok": OK_GREEN, "warning": WARN_ORANGE,
            "info": TEXT_MUTED, "path": ACCENT
        }
        for tag, color in tag_colors.items():
            self.env_tree.tag_configure(tag, foreground=color)
            self.devices_tree.tag_configure(tag, foreground=color)

    # ------------------------------------------------------------------
    # 主要功能与事件处理 (Main Logic & Event Handlers)
    # ------------------------------------------------------------------
    def browse_folder(self):
        if not self._alive: return
        path = filedialog.askdirectory(title="请选择 iOS 项目根目录")
        if path: self.project_root.set(path)

    def start_check(self):
        """防抖地启动后台检测线程"""
        if self._detection_in_progress: return
        self._detection_in_progress = True

        self.time_lbl.config(text="检测中...")
        self._clear_trees()

        threading.Thread(target=self._background_check_worker, daemon=True).start()

    def _background_check_worker(self):
        """后台工作线程，调用纯逻辑函数并调度UI更新"""
        try:
            # 1. 获取环境检测结果
            log_lines = get_full_check_results()
            if self._alive: self.after(0, self._populate_env_tree, log_lines)

            # 2. 获取设备列表
            success, devices = get_connected_ios_devices()
            if self._alive: self.after(0, self._populate_devices_tree, success, devices)
        finally:
            self._detection_in_progress = False
            if self._alive:
                now = time.strftime('%Y-%m-%d %H:%M:%S')
                self.after(0, lambda: self.time_lbl.config(text=f"最后检测时间: {now}"))

    def _clear_trees(self):
        """清空两个Treeview的内容"""
        if self.env_tree.winfo_exists(): self.env_tree.delete(*self.env_tree.get_children())
        if self.devices_tree.winfo_exists(): self.devices_tree.delete(*self.devices_tree.get_children())

    def _populate_env_tree(self, log_lines):
        """根据日志行，构建层级分明的环境依赖树"""
        if not self._alive or not self.env_tree.winfo_exists(): return

        current_parent = ""  # 指向 '--- Title ---'
        current_task = ""  # 指向 '[*] Task'

        for line in log_lines:
            line = line.strip()
            if not line: continue

            if line.startswith("---"):
                current_parent = self.env_tree.insert("", "end", text=line.strip("- "), open=True)
                current_task = ""  # 重置任务节点
            elif line.startswith("[*]"):
                parent = current_parent or ""
                current_task = self.env_tree.insert(parent, "end", text=line.replace("[*]", "").strip(), open=True)
            else:
                # 结果行，应插入到当前任务节点下
                parent = current_task or current_parent or ""
                tag = self._get_tag_from_line(line)
                self.env_tree.insert(parent, "end", text=line.lstrip("    "), tags=(tag,))

    def _get_tag_from_line(self, line):
        """根据行首的符号返回对应的样式标签"""
        if line.startswith("✅"): return "ok"
        if line.startswith("❌"): return "error"
        if line.startswith("⚠️"): return "warning"
        if line.strip().startswith("-"): return "path"
        return "info"

    def _populate_devices_tree(self, success, devices):
        """填充连接设备列表"""
        if not self._alive or not self.devices_tree.winfo_exists(): return

        root = self.devices_tree.insert("", "end", text="连接设备", open=True)
        if not devices:
            self.devices_tree.insert(root, "end", text="未检测到设备", tags=("warning",))
            return

        for dev_line in devices:
            tag = "ok" if success and not ("错误" in dev_line or "注意" in dev_line) else "warning"
            self.devices_tree.insert(root, "end", text=dev_line, tags=(tag,))

    # ------------------------------------------------------------------
    # 打包上传流程 (UI 部分)
    # ------------------------------------------------------------------
    def build_project(self):
        path = self.project_root.get().strip()
        if not path or not os.path.isdir(path):
            messagebox.showwarning("路径无效", "请先选择一个有效的项目根目录！", parent=self)
            return

        self._show_packing_progress_window()
        threading.Thread(target=self._run_upload_task, args=(path,), daemon=True).start()

    def _show_packing_progress_window(self):
        if hasattr(self, "_pack_win") and self._pack_win.winfo_exists():
            self._pack_win.lift()
            return

        self._pack_win = tk.Toplevel(self)
        self._pack_win.title("项目上传至 WSL")
        self.pack_win.geometry("700x450")
        self._pack_win.transient(self)
        self._pack_win.grab_set()
        # 绑定关闭事件，确保安全
        self._pack_win.protocol("WM_DELETE_WINDOW", self._on_pack_win_close)

        ttk.Label(self._pack_win, text="正在上传项目文件至WSL，请稍候...").pack(pady=10)
        self.pack_pb = ttk.Progressbar(self._pack_win, mode="indeterminate")
        self.pack_pb.pack(fill=tk.X, padx=20, pady=5)
        self.pack_pb.start()

        log_frame = ttk.Frame(self._pack_win)
        log_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        self.pack_log = tk.Text(log_frame, state="disabled", wrap="word")
        self.pack_log.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        log_scroll = ttk.Scrollbar(log_frame, command=self.pack_log.yview)
        log_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        self.pack_log.configure(yscrollcommand=log_scroll.set)

    def _run_upload_task(self, path):
        """后台线程，调用纯逻辑的上传函数"""
        try:
            upload_project_to_wsl(
                source_dir=path,
                log_callback=lambda msg: self.after(0, self._log_to_pack_window, msg),
                message_callback=lambda title, msg: self.after(0, self._show_pack_message, title, msg)
            )
        finally:
            if self._alive and hasattr(self, 'pack_pb') and self.pack_pb.winfo_exists():
                self.after(0, self.pack_pb.stop)

    def _log_to_pack_window(self, text: str):
        if self._alive and hasattr(self, 'pack_log') and self.pack_log.winfo_exists():
            self.pack_log.config(state="normal")
            self.pack_log.insert(tk.END, text + "\n")
            self.pack_log.config(state="disabled")
            self.pack_log.see(tk.END)

    def _show_pack_message(self, title: str, message: str):
        if self._alive and hasattr(self, '_pack_win') and self._pack_win.winfo_exists():
            messagebox.showinfo(title, message, parent=self._pack_win)
            self._pack_win.destroy()  # 显示消息后自动关闭日志窗口

    def _on_pack_win_close(self):
        """处理日志窗口被手动关闭的情况"""
        if messagebox.askyesno("确认", "正在上传项目，关闭此窗口将无法看到日志。确定要关闭吗？", parent=self._pack_win):
            self._pack_win.destroy()